﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using Newtonsoft.Json;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.ServiceComponent.DAC.Service;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Base.Dao;

namespace T.FAS.Runtime.DataModel.Dao
{
    /// <summary>
    /// CNO ELB数据访问类
    /// </summary>
    public class CompositeNodeObjectELBDao : DaoService<CompositeNodeObject>
    {
        public override string TableName => "FAS_CompositeNodeObject";
        public override string IDColumnName => "ID";
        public string ForeignColumn => "CompositeDataObjectID";
        public override List<string> ExceptColumnName {get;} = DaoUtil.GetExceptionColumn<CompositeNodeObject>();

        private readonly CompositeNodeObjectElementELBDao _nodeObjectElementELBDao = new CompositeNodeObjectElementELBDao();
        private readonly AssociationELBDao _associationELBDao = new AssociationELBDao();

        public CompositeNodeObjectELBDao() : base()
        {
            DBName = "TFAS";
        }

        /// <summary>
        /// 获取元数据内容
        /// </summary>
        /// <param name="metaDataId"></param>
        /// <returns></returns>
        public List<CompositeNodeObject> GetCompositeNodeObjects(string cdoId)
        {
            var result = new List<CompositeNodeObject>();
            if (string.IsNullOrEmpty(cdoId))
            {
                return result;
            }
            List<object> objects = base.GetObjectsByFilter($"{ForeignColumn}='{cdoId}'");
            if (objects != null)
            {
                objects.ForEach(obj => {
                    var cno = obj as CompositeNodeObject;
                    //cno.Elements = nodeObjectElementELBDao.GetCompositeNodeObjectElements(cno.ID);
                    //cno.Associations = AssociationELBDao.GetAssociations(cno.ID);
                    result.Add(cno);
                });
            }
            return result;
        }

        /// <summary>
        /// 获取所有引用指定DO的CNO集合
        /// </summary>
        /// <param name="doId"></param>
        /// <returns></returns>
        public List<CompositeNodeObject> GetCNOByReferSpecificDO(string doId)
        {
            var result = new List<CompositeNodeObject>();
            if (string.IsNullOrEmpty(doId))
            {
                return result;
            }
            List<object> objects = this.GetObjectsByFilter($"DataObjectID='{doId}'");
            if (objects != null)
            {
                objects.ForEach(obj => {
                    var cno = obj as CompositeNodeObject;
                    //cno.Elements = nodeObjectElementELBDao.GetCompositeNodeObjectElements(cno.ID);
                    result.Add(cno);
                });
            }
            return result;
        }

        /// <summary>
        /// 添加CNO|Element
        /// </summary>
        /// <param name="compositeNodeObjects"></param>
        public void CreateCompositeNodeObject(List<CompositeNodeObject> compositeNodeObjects)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    base.Add(compositeNodeObjects);
                    _nodeObjectElementELBDao.Add(compositeNodeObjects.SelectMany(node => node.Elements).ToList());
                    _associationELBDao.Add(compositeNodeObjects.SelectMany(node => node.Associations).ToList());
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.CDO.CreateCNOError, e.Message, e);
            }
        }

        /// <summary>
        /// 删除CNO|Element
        /// </summary>
        /// <param name="cdoId">CDO id</param>
        public void DeleteCompositeNodeObjects(string cdoId)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    var CNOs = GetCompositeNodeObjects(cdoId);
                    foreach (var CNO in CNOs)
                    {
                        _nodeObjectElementELBDao.DeleteCompositeNodeObjectElement(CNO.ID);
                        _associationELBDao.DeleteAssociation(CNO.ID);
                    }
                    base.DB.ExecSqlStatement(string.Format(DaoUtil.DeleteSQLWithNoParam, this.TableName, this.ForeignColumn, cdoId));
                    scope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.CDO.DeleteCNOError, e.Message, e);
            }
        }

        /// <summary>
        /// 删除CNO|Element
        /// </summary>
        /// <param name="metaDataID">CDO id</param>
        public void DeleteByMetaDataForeignKey(string metaDataID)
        {
            try
            {
                base.DB.ExecSqlStatement(string.Format(DaoUtil.DeleteSQLWithNoParam, this.TableName, this.ForeignColumn, metaDataID));
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.CDO.DeleteCNOError, e.Message, e);
            }
        }
    }
}
